#include "RegUtils.h"
#include "Server.h"

#define SERVICE_NAME "SO2 - Scramble Server"

SERVICE_STATUS          MyServiceStatus; 
SERVICE_STATUS_HANDLE   MyServiceStatusHandle;

VOID  WINAPI MyServiceStart (DWORD argc, LPTSTR *argv); 
VOID  WINAPI MyServiceCtrlHandler (DWORD opcode); 
DWORD WINAPI ProcCliente(LPVOID param);

BOOL flag;
HANDLE StopEvent;

int status;


HANDLE hEventSource;

void MostrarErro(LPSTR str,DWORD val)
{
	char buf[1024];
	LPSTR msg[2]={buf,NULL};

	wsprintf(buf,str,val);

	if (!hEventSource) {
		hEventSource = RegisterEventSource(NULL,            // local machine
			SERVICE_NAME); // source name
	}

	if (hEventSource) {
		ReportEvent(hEventSource,
			EVENTLOG_INFORMATION_TYPE,
			0,
			0,
			NULL,   // sid
			1,
			0,
			(const char **)msg,
			NULL);
	}

}

void WINAPI MyServiceStart(DWORD argc, LPTSTR *argv) 
{

	MyServiceStatus.dwServiceType        = SERVICE_WIN32; 
	MyServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 
	MyServiceStatus.dwControlsAccepted   = 0;
	MyServiceStatus.dwWin32ExitCode      = 0; 
	MyServiceStatus.dwServiceSpecificExitCode = 0; 
	MyServiceStatus.dwCheckPoint         = 0; 
	MyServiceStatus.dwWaitHint           = 0; 

	MyServiceStatusHandle = RegisterServiceCtrlHandler( 
		SERVICE_NAME, 
		MyServiceCtrlHandler); 

	if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) 
	{ 
		MostrarErro(" [ServNT] RegisterServiceCtrlHandler failed %d\n", GetLastError()); 
		return; 
	} 

	if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) 
	{ 
		status = GetLastError(); 
		MostrarErro(" [ServNT] SetServiceStatus error %ld\n",status);
		return;
	} 

	StopEvent=CreateEvent(NULL,FALSE,FALSE,NULL);

	if (StopEvent == NULL) {
		status = GetLastError(); 
		MostrarErro(" [ServNT] CreateEvent error %ld\n",status);
		return;
	}	
	
	
	// Inicia o servidor
	Server::Instance();

	// Initialization complete - report running status. 
	MyServiceStatus.dwCurrentState       = SERVICE_RUNNING; 
	MyServiceStatus.dwCheckPoint         = 0; 
	MyServiceStatus.dwWaitHint           = 0; 
	MyServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP; // | SERVICE_ACCEPT_PAUSE_CONTINUE; 

	if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) 
	{ 
		status = GetLastError(); 
		MostrarErro(" [ServNT] SetServiceStatus error %ld\n",status);
		return;
	} 


	WaitForSingleObject(StopEvent,INFINITE);
	delete Server::Instance();

	CloseHandle(StopEvent);

	MyServiceStatus.dwCurrentState       = SERVICE_STOPPED; 
	MyServiceStatus.dwCheckPoint         = 0; 
	MyServiceStatus.dwWaitHint           = 0; 

	if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) 
	{ 
		status = GetLastError(); 
		MostrarErro(" [ServNT] SetServiceStatus error %ld\n",status); 
	} 


	return; 
} 

VOID WINAPI MyServiceCtrlHandler (DWORD Opcode) 
{ 
	switch(Opcode) 
	{ 
	case SERVICE_CONTROL_PAUSE: 
		// Do whatever it takes to pause here. 
		MyServiceStatus.dwCurrentState = SERVICE_PAUSED; 
		break; 

	case SERVICE_CONTROL_CONTINUE: 
		// Do whatever it takes to continue here. 
		MyServiceStatus.dwCurrentState = SERVICE_RUNNING; 
		break; 

	case SERVICE_CONTROL_STOP: 
		// Do whatever it takes to stop here. 
		MyServiceStatus.dwWin32ExitCode = 0; 
		MyServiceStatus.dwCurrentState  = SERVICE_STOP_PENDING; 
		MyServiceStatus.dwCheckPoint    = 0; 
		MyServiceStatus.dwWaitHint      = 0; 

		if (!SetServiceStatus (MyServiceStatusHandle, 
			&MyServiceStatus))
		{ 
			status = GetLastError(); 
			MostrarErro(" [ServNT] SetServiceStatus error %ld\n",status); 
		} 

		SetEvent(StopEvent);

		MostrarErro(" [ServNT] Leaving MyService \n",0); 
		return; 

	case SERVICE_CONTROL_INTERROGATE: 
		// Fall through to send current status. 
		break; 

	default: 
		MostrarErro(" [ServNT] Unrecognized opcode %ld\n", 
			Opcode); 
		break;
	} 

	// Send current status. 
	if (!SetServiceStatus (MyServiceStatusHandle,  &MyServiceStatus)) 
	{ 
		status = GetLastError(); 
		MostrarErro(" [ServNT] SetServiceStatus error %ld\n",status); 
	} 
	return; 
} 

void main()
{
	SERVICE_TABLE_ENTRY dispatchTable[] = 
	{
		{SERVICE_NAME, MyServiceStart},
		{NULL, NULL	}
	};
	
	if (!StartServiceCtrlDispatcher( dispatchTable)) 
	{ 
		MostrarErro(" [ServNT] StartServiceCtrlDispatcher error = %d\n", GetLastError()); 
	}
	/*
	Server::Instance();
	getchar();
	/*Player player;
	player.Username("Avelino");
	player.Password("pass");
	player.AllTimePoints(100000);
	player.BestScore(500);
	player.TotalGamesPlayed(10);

	//RegUtils::playerExists("teste");
	RegUtils::CreatePlayer(player);
	RegUtils::SavePlayerInfo(player);

	Player player1;
	player1.Username("Avelino");
	RegUtils::LoadPlayerInfo(player1);
	*/

	//getchar();
}